package com.ganeshkrishnan.globald.web.controller;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpSession;

import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ganeshkrishnan.globald.dao.PersonDao;
import com.ganeshkrishnan.globald.dao.PersonLocationDao;
import com.ganeshkrishnan.globald.model.CivResource;
import com.ganeshkrishnan.globald.model.Person;
import com.ganeshkrishnan.globald.model.PersonLocation;
import com.ganeshkrishnan.globald.web.utils.Constants;

@Controller
@RequestMapping(value = "/maps")
public class MapsController {
	@Autowired
	private PersonDao			personDao;
	@Autowired
	private PersonLocationDao	personlocationdao;

	public PersonDao getPersonDao() {
		return personDao;
	}

	public void setPersonDao(PersonDao personDao) {
		this.personDao = personDao;
	}

	public PersonLocationDao getPersonlocationdao() {
		return personlocationdao;
	}

	public void setPersonlocationdao(PersonLocationDao personlocationdao) {
		this.personlocationdao = personlocationdao;
	}

	public MapsController() {
	}

	@RequestMapping(value = "/addlocations", method = RequestMethod.GET)
	public @ResponseBody
	Map<String, String> addLocation(@RequestParam float lat, @RequestParam float lon, @RequestParam int terdistance,
			HttpSession session) throws JSONException {
		Map<String, String> map = new HashMap<String, String>();
		Long personID = (Long) session.getAttribute("personID");
		if (null == personID || terdistance < 1) {

			// return "Status:-401"
			map.put(Constants.STATUS, "-ER");
			map.put(Constants.CODE, "401");
			return map;
		}

		Person person = personDao.get(personID);
		//FIXME need basic calculations to make sure that distance is not being manipulated

		Set<CivResource> res = person.getResource();
		for (CivResource civResource : res) {
			int cost = terdistance * (civResource.getResType() + 1);
			long resAvail = civResource.getResAvailable();
			if (cost > resAvail) {
				map.put(Constants.STATUS, "-ER");
				map.put(Constants.CODE, "201");
				return map;
			}
			civResource.setResAvailable(resAvail - cost);
			res.add(civResource);
		}
		person.setResource(res);

		PersonLocation location = new PersonLocation();
		location.setPerson(person);
		location.setLatitude(lat);
		location.setLongitude(lon);
		location.setLocationType(Constants.LocationType.SATELLITE.ordinal());
		//location.setDeployment(0);
		personlocationdao.save(location);
		return map;
	}

	@RequestMapping(value = "/getmylocations", method = RequestMethod.GET)
	public @ResponseBody
	Map<String, Object> getMyLocation(@RequestParam float nlat, @RequestParam float nlon, @RequestParam float slat,
			@RequestParam float slon, HttpSession session) throws JSONException {
		Map<String, Object> map = new HashMap<String, Object>();
		Long personID = (Long) session.getAttribute("personID");
		if (null == personID) {

			map.put(Constants.STATUS, "-ER");
			map.put(Constants.CODE, "401");
			return map;
		}
		List<PersonLocation> list = personlocationdao.findMySatellitesbyBounds(personID, nlat, nlon, slat, slon);
		Iterator<PersonLocation> it = list.iterator();
		while (it.hasNext()) {
			PersonLocation loc = (PersonLocation) it.next();
			map.put(loc.getID().toString(), loc.getLatitude() + "/" + loc.getLongitude());
		}
		return map;
	}

	@RequestMapping(value = "/getcombatant", method = RequestMethod.GET)
	public @ResponseBody
	Map<String, Object> getCombatants(@RequestParam float nlat, @RequestParam float nlon, @RequestParam float slat,
			@RequestParam float slon, @RequestParam int hc, HttpSession session) throws JSONException {
		Map<String, Object> map = new HashMap<String, Object>();
		Long personID = (Long) session.getAttribute("personID");
		if (null == personID) {
			personID = 13l;
			// return "Status:-401"
			map.put(Constants.STATUS, "-ER");
			map.put(Constants.CODE, "401");
			return map;
		}
		//FIXME the home country variable hc should either be retrieved from session or DB.
		List<Object[]> list = personlocationdao.findCombatantsbyCountryBounds(personID, nlat, nlon, slat, slon, hc);
		for (Object[] obj : list) {
			if (obj.length == 4) {
				map.put(obj[0] + "", obj[1] + "/" + obj[2] + "/" + obj[3]);
			}
		}
		//			PersonLocation loc = (PersonLocation) it.next();
		//			map.put(loc.getID().toString(), loc.getLatitude() + "/" + loc.getLongitude() + "/" + loc.getPerson().getId() + "/"
		//					+ loc.getPerson().getFirstName());
		return map;
	}

	// initializing method
	@RequestMapping(method = RequestMethod.GET)
	public String getCreateForm(Model model, HttpSession session) {
		return "redirect:/country";
	}

	//------------ experimental features
	@RequestMapping(value = "/getperson", method = RequestMethod.GET)
	public @ResponseBody
	Person getPerson(@RequestParam int personid, HttpSession session) {
		Long personID = (Long) session.getAttribute("personID");
		if (null == personID) {
			return null;
		}
		Person p = personDao.get(personID);
		//List l = p.getResource();
		//System.out.println(l.get(0));
		return p;
	}
}
